#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "logger.h"
#include "queue.h"

queue_t *queue_create(void) {
	queue_t *queue = (queue_t *)malloc(sizeof(queue_t));

	queue->tail = queue->head = (record_t *)malloc(sizeof(record_t));
	queue->head->next = queue->tail->next = NULL;

	memset(queue->head->message, 0, MESSAGE_MAXLEN);
	memset(queue->tail->message, 0, MESSAGE_MAXLEN);
	return queue;
}

void queue_destroy(queue_t *queue) {
	free(queue->head);
	free(queue);
}

void enqueue(queue_t *queue, char *data) {
	record_t *record = (record_t *)malloc(sizeof(record_t)), *p;
	int succ;
	strncpy(record->message, data, MESSAGE_MAXLEN);
	record->next = NULL;
	do {
		p = queue->tail;
		succ = __sync_bool_compare_and_swap((unsigned int*)&p->next, 0, (unsigned int)record);
		if (!succ) {
			__sync_bool_compare_and_swap((unsigned int*)&queue->tail,
					(unsigned int)p, (unsigned int)p->next);
		}
	} while (!__sync_bool_compare_and_swap((unsigned int*)&queue->tail,
				(unsigned int)p, (unsigned int)record));
	(record_t *)queue->tail;
}

char *dequeue(queue_t *queue) {
	record_t *p;
	do {
		p = queue->head;
		if (!p->next)
			return NULL;
	} while (!__sync_bool_compare_and_swap((unsigned int*)&queue->head,
				(unsigned int)p, (unsigned int)p->next));
	(record_t *)queue->head;
	char *data = p->next->message;
	free(p);
	return data;
}
